﻿using System;
using System.IO;
using System.Linq;
using System.Text;
using Com.Pernix.Common.File;
using Com.Pernix.Common.Log.Abstracts;
using Com.Pernix.Common.Log.Configs;

namespace Com.Pernix.Common.Log
{
    internal class LogWriter:ILogWriter
    {
        private readonly LogConfiguration _config;
        public LogWriter(LogConfiguration logConfiguration)
        {
            _config = logConfiguration;
        }
        public void Write(ILogMsg message)
        {
            try
            {
                PrepareDir(_config.FilePath);
                var filename = _config.FilePath;
                if (_config.FileSize > 0)
                {
                    filename = GetFileNameWithSizeCriteria(_config);
                }
                filename = AddDateToFileName(filename);

                using (var fileToWrite = new StreamWriter(filename, true, Encoding.UTF8))
                {
                    fileToWrite.WriteLine(message.GetMessage());
                }
            }
            catch (Exception)
            {
                ;
            }
        }

        private string AddDateToFileName(string filename)
        {
            var filenameWithOutExtension = Path.GetFileNameWithoutExtension(filename);
            var fileExtension = Path.GetExtension(filename);
            filenameWithOutExtension += DateTime.Now.ToString("-yyyyMMdd");
            var newFileName = filenameWithOutExtension + fileExtension;
            return filename.Replace(Path.GetFileName(filename), newFileName);
        }

        private void PrepareDir(string filePath)
        {
            var directory = FileUtil.GetDirectory(_config.FilePath);
            var dirInfo = new DirectoryInfo(directory);
            if (!dirInfo.Exists)
            {
                dirInfo.Create();
            }
        }

        private static string GetFileNameWithSizeCriteria(LogConfiguration config)
        {
            var fileInfo = new FileInfo(config.FilePath);
            if (fileInfo.Exists)
            {
                var size = fileInfo.Length/1024;
                if (size > config.FileSize)
                {
                    //create a new filename when the old file size is over filesize configuration.
                    var directory = FileUtil.GetDirectory(config.FilePath);
                    var filename = Path.GetFileName(config.FilePath);
                    var filenames = FileUtil.GetFileNameInDir(directory);
                    var targetFileInDirectory = filenames.Where(p => Path.GetFileName(p).StartsWith(filename));
                    var ext = targetFileInDirectory.Count() + 1;
                    return config.FilePath + ext;
                }
            }
            return config.FilePath;
        }
    }
}
